package com.my.commonlib.util;

import android.content.Context;
import android.content.res.Resources;
import android.graphics.Bitmap;
import android.graphics.BitmapShader;
import android.graphics.Canvas;
import android.graphics.Paint;
import android.graphics.RectF;
import android.net.Uri;
import android.widget.ImageView;

import com.bumptech.glide.Glide;
import com.bumptech.glide.RequestManager;
import com.bumptech.glide.load.engine.bitmap_recycle.BitmapPool;
import com.bumptech.glide.load.resource.bitmap.BitmapTransformation;
import com.my.commonlib.R;

import java.io.File;

public class GlideImageUtil {

    private static GlideImageUtil instance = null;
    /* 私有构造方法，防止被实例化 */
    private GlideImageUtil() {
    }

    /* 1:懒汉式，静态工程方法，创建实例 */
//    public static GlideImageUtil getInstance() {
//        if (instance == null) {
//            instance = new GlideImageUtil();
//        }
//        return instance;
//    }

    /* 2.懒汉式变种，解决线程安全问题
    加上synchronized，但是每次调用实例时都会加载**/
//    public static GlideImageUtil getInstance() {
//        synchronized (GlideImageUtil.class) {
//            if (instance == null) {
//                instance = new GlideImageUtil();
//            }
//        }
//        return instance;
//    }

//    /*3.双重锁定:只在第一次初始化的时候加上同步锁*/
    public static GlideImageUtil getInstance() {
        if (instance == null) {
            synchronized (GlideImageUtil.class) {
                if (instance == null) {
                    instance = new GlideImageUtil();
                }
            }
        }
        return instance;
    }


    public void glideLoadImage(Context context, String ImagePath, ImageView imageView, int placeRes, int errRes){
        /**
         * dontAnimate() 如果你想直接显示图片而没有任何淡入淡出效果
         * centerCrop() 这是(对于当前版本3.6.1)默认激活的,.crossFade(int duration)。如果你想要去减慢（或加快）动画，随时可以传一个毫秒的时间给这个方法。动画默认的持续时间是 300毫秒。
         *  placeholder,centerCrop,error需要知道的是所有这些参数都是独立的，而不需要彼此依赖的。比如，你可以设定 .error() 而不调用 .placeholder()。
         *                              你可能设置 crossFade() 动画而没有占位符。任何参数的组合都是可能的。
         *  override(600, 200)  调用 override(horizontalSize, verticalSize) 。这将在图片显示到 ImageView之前重新改变图片大小。
         *  CenterCrop()是一个裁剪技术，即缩放图像让它填充到 ImageView 界限内并且侧键额外的部分。ImageView 可能会完全填充，但图像可能不会完整显示。
         *  fitCenter() 是裁剪技术，即缩放图像让图像都测量出来等于或小于 ImageView 的边界范围。该图像将会完全显示，但可能不会填满整个 ImageView。
         *  asGif()  强制 Glide变成一个 Gif :
         *  .asBitmap()  Gif 的第一帧
         *  显示本地视频   网络视频 用 VideoView
         *      String filePath = "/storage/emulated/0/Pictures/example_video.mp4";
                 Glide
                 .with( context )
                 .load( Uri.fromFile( new File( filePath ) ) )
                 .into( imageViewGifAsBitmap );
         *
         * .skipMemoryCache(true) 告诉 Glide 跳过内存缓存。不会把图片放到内存缓存中去。Glide 将会仍然利用磁盘缓存来避免重复的网络请求。 默认false
         * .diskCacheStrategy(DiskCacheStrategy.NONE) 不缓存 磁盘
         *                    DiskCacheStrategy.NONE 什么都不缓存，就像刚讨论的那样
                              DiskCacheStrategy.SOURCE 仅仅只缓存原来的全分辨率的图像。在我们上面的例子中，将会只有一个 1000x1000 像素的图片
                              DiskCacheStrategy.RESULT 仅仅缓存最终的图像，即，降低分辨率后的（或者是转换后的）
                              DiskCacheStrategy.ALL 缓存所有版本的图像（默认行为）

            。priority( Priority.HIGH ) 优先级
                         Priority.LOW
                         Priority.NORMAL
                         Priority.HIGH
                         Priority.IMMEDIATE
         *
         *  .thumbnail(0.1f) 简单的缩略图 float 作为其大小的倍数
         *
         *  SimpleTarget  //加载结束后 得到 bitmap
         *
         *  private SimpleTarget target = new SimpleTarget<Bitmap>(){
                @Override
                public void onResourceReady(Bitmap bitmap, GlideAnimation<? super Bitmap> glideAnimation) {
                //完所有的加载和处理之后,加载出来bitmap
                //imageView1.setImageBitmap( bitmap );
                }
             };
         *
         *  ViewTarget  //自定义控件中使用 到的 glide
         *  viewTarget = new ViewTarget<FutureStudioView, GlideDrawable>( customView ) {
                @Override
                public void onResourceReady(GlideDrawable resource, GlideAnimation<? super GlideDrawable> glideAnimation) {
                this.view.setImage( resource.getCurrent() );
                }
            };
         *
         *  NotificationTarget  在通知栏目上显示 网络图片
         *  notificationTarget = new NotificationTarget(
             context,
             rv,
             R.id.remoteview_notification_icon,
             notification,
             NOTIFICATION_ID);
         *
         *  AppWidgetProvider  App Widgets 应用小部件
         *
         *  .transform( new RotateTransformation( context, 90f )) 旋转图片 90 度
         *
         */

        Glide.with(context)
                .load(ImagePath)
                .placeholder(placeRes)
                .error(errRes)
                .centerCrop()
                .dontAnimate()
                .into(imageView);
    }

    public void glideLoadImage(Context context, String ImagePath, ImageView imageView, int placeRes, boolean flag){
        Glide.with(context)
                .load(ImagePath)
                .placeholder(placeRes)
                .error(placeRes)
                .into(imageView);
    }

    public void glideLoadImageDefaultHeard(Context context, String ImagePath, ImageView imageView){
        glideLoadImage(context, ImagePath, imageView, R.drawable.error_heard, R.drawable.error_heard);
    }
    public void glideLoadImage(Context context, String ImagePath, ImageView imageView){
        glideLoadImage(context,ImagePath,imageView, 0,0);
    }
    public void glideLoadImage(Context context, String ImagePath, ImageView imageView, int allres){
        glideLoadImage(context,ImagePath,imageView, allres,allres);
    }

    public RequestManager getGlide(Context context){
       if(null != context)
           return Glide.with(context);
        return null;
    }

    public void glideLoadImage(Context context, int resID, ImageView imageView){
        Glide.with(context)
                .load(resID)
                .into(imageView);
    }

    public void glideLoadImage(Context context, File file, ImageView imageView){
        Glide.with(context)
                .load(file)
                .into(imageView);
    }

    public void glideLoadImage(Context context, Uri uri, ImageView imageView){
        Glide.with(context)
                .load(uri)
                .into(imageView);
    }

    public void glideCircleLoadImage(Context context, String url, ImageView imageView, int round, int defaultImg){
        getGlide(context)
                .load(url)
                .placeholder(defaultImg)
                .error(defaultImg)
                .transform(new GlideRoundTransform(context, round))
                .into(imageView);
    }



    public class GlideRoundTransform extends BitmapTransformation {
        float radius = 0f;

        public GlideRoundTransform(Context context) {
            this(context, 4);
        }

        public GlideRoundTransform(Context context, int dp) {
            super(context);
            this.radius = Resources.getSystem().getDisplayMetrics().density * dp;
        }

        @Override
        protected Bitmap transform(BitmapPool pool, Bitmap toTransform, int outWidth, int outHeight) {
            return roundCrop(pool, toTransform);
        }

        private Bitmap roundCrop(BitmapPool pool, Bitmap source) {
            if (source == null) return null;

            Bitmap result = pool.get(source.getWidth(), source.getHeight(), Bitmap.Config.ARGB_8888);
            if (result == null) {
                result = Bitmap.createBitmap(source.getWidth(), source.getHeight(), Bitmap.Config.ARGB_8888);
            }

            Canvas canvas = new Canvas(result);
            Paint paint = new Paint();
            paint.setShader(new BitmapShader(source, BitmapShader.TileMode.CLAMP, BitmapShader.TileMode.CLAMP));
            paint.setAntiAlias(true);
            RectF rectF = new RectF(0f, 0f, source.getWidth(), source.getHeight());
            canvas.drawRoundRect(rectF, radius, radius, paint);
            return result;
        }

        @Override
        public String getId() {
            return getClass().getName() + Math.round(radius);
        }
    }


}
